/*!***************************************************
 * @file: comm_protocol.h
 * @brief: 通信协议的头文件
 * @author: ITHAO 
 * @date: 2018.10.30
 * @note: 
 ****************************************************/

#ifndef __COMM_PROTOCOL_H__
#define __COMM_PROTOCOL_H__

typedef unsigned char       uint8;
typedef unsigned short      uint16;
typedef unsigned int        uint32;
typedef unsigned long long	u64;
typedef unsigned char		    uint8;
typedef unsigned short		  uint16;
typedef unsigned int		    uint32;
typedef unsigned long long	uint64;

#define SUCCESS 1
#define FAULT   0
#define FAIL    0
#ifndef TRUE
#define TRUE    1
#endif

#define IP_ADDR     "192.168.70.128"
#define SERVER_PORT 6666
#define BACKLOG     10

/*32位拆解与合并*/
#define BREAK_UINT32( var, ByteNum ) \
          (uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF))

#define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \
          ((uint32)((uint32)((Byte0) & 0x00FF) \
          + ((uint32)((Byte1) & 0x00FF) << 8) \
          + ((uint32)((Byte2) & 0x00FF) << 16) \
          + ((uint32)((Byte3) & 0x00FF) << 24)))

/*将两个一字节的变量构成一个两字节的变量*/
#define BUILD_UINT16(loByte, hiByte) \
          ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))
/*将一个两字节的变量拆分为两个一字节的变量*/
#define HI_UINT16(a) (((a) >> 8) & 0xFF)
#define LO_UINT16(a) ((a) & 0xFF)

/*8位拆解与合并*/
#define BUILD_UINT8(hiByte, loByte) \
          ((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4)))
#define HI_UINT8(a) (((a) >> 4) & 0x0F)
#define LO_UINT8(a) ((a) & 0x0F)

/*************底层通信协议******************/
/*帧头*/
#define DATA_HEADER_FIRST                   0xAA
#define DATA_HEADER_SECOND                  0x55
/*ACK ERROR 应答错误宏定义*/  
#define ACK_OK                              0x00
#define ACK_RECV_HEAD_FIRST_ERR             0xE1 
#define ACK_RECV_HEAD_SECOND_ERR            0xE2
#define ACK_RECV_LENGTH_ERR                 0xE3  
#define ACK_RECV_LRC_ERR                    0xE4


/*************顶层通信协议******************/
/*通用应答*/
#define SHORT_OF_DATA_ACK                   0Xff
#define WRONG_CMD_TYPE_ACK                  0xfe
#define WRONG_CMD_ACK                       0xfd

/*登陆相关部分*/
/*命令类型*/
#define LOGIN_CMD_TYPE                      0xC0
/*命令*/
#define LOGIN_CMD                           0x01
#define REGISTER_CMD                        0x02
#define CHECK_ONLINE_CMD                    0x03
#define LOGOUT_CMD                          0x04
#define LOGOUT_BY_SERVER_CMD                0x05
/*ACK*/
#define LOGIN_SUCCESS_ACK                   0x00
#define LOGIN_PASSWORD_ERR_ACK              0x01
#define LOGIN_ACCOUNT_NOT_EXIXT_ACK         0x02
#define LOGIN_NUM_TOO_MUCH_ACK              0x03
#define LOGIN_ALREADY_LGOIN_ACK             0x04

#define REGISTER_SUCCESS_ACK                0X00
#define REGISTER_ACCOUNT_EXIST_ACK          0x01

#define CHECK_ONLINE_ACK                    0X00
#define CHECK_OFFLINE_ACK                   0X01

#define LOGOUT_SUCCESS_ACK                  0x00
#define LOGOUT_NOT_ONLINE_ACK               0x01

/*好友相关部分*/
/*命令类型*/
#define FRIEND_CMD_TYPE                     0xC1
/*命令*/
#define LOAD_FRIEND_CMD                     0x01
#define ADD_FRIEND_CMD                      0x02
#define REMOVE_FRIEND_CMD                   0x03
#define FRIEND_ONLINE_CMD                   0x04
#define FRIEND_OFFLINE_CMD                  0x05

/*ACK*/
#define LOAD_SUCCESS_ACK                    0x00
#define LOAD_SENDING_ACK                    0x01
/*服务器执行相应函数出错时返回这个ack*/
#define LOAD_FAIL_ACK                       0x02 
#define LOAD_NO_OWNER_INFO_ACK              0x03
#define LOAD_ACCOUNT_NOT_EXIST_ACK          0x04

#define ADD_SUCCESS_ACK                     0x00
/*服务器执行相应函数出错时返回这个ack*/
#define ADD_FAIL_ACK                        0x01
#define ADD_OWNERACCOUNT_NOT_EXIST_ACK      0x02
#define ADD_FRIENDACCOUNT_NOT_EXIST_ACK     0x03
#define ADD_EXCEED_FRIEND_NUM               0x04
#define ADD_IS_FRIEND_ALREADY_ACK           0x05
#define ADD_FRIEND_ADD_OWNER_FAIL_ACK       0x06
#define ADD_GET_NEW_FRIEND_ACK              0x07

#define REMOVE_SUCCESS_ACK                  0x00
/*服务器执行相应函数出错时返回这个ack*/
#define REMOVE_FAIL_ACK                     0x01
#define REMOVE_OWERACCOUNT_NOT_EXIST_ACK    0x02
#define REMOVE_FRIENDACCOUNT_NOT_EXIST_ACK  0x03
#define REMOVE_NO_OWNER_INFO_ACK            0x04
#define REMOVE_NOT_FRIEND_ACK               0x05
#define REMOVE_FRIEND_RMOVE_OWNER_FAIL_ACK  0x06
#define REMOVE_LOSE_FRIEND_ACK              0x07

/*聊天相关部分*/
/*命令类型*/
#define CHAT_CMD_TYPE                       0xC2
/*命令*/
/*ack*/
#define CHAT_SEND_SUCCESS_ACK               0x00
#define CHAT_SENDACCOUNT_NOT_EXIST_ACK      0x01
#define CHAT_RECVACCOUNT_NOT_EXIST_ACK      0x02



#define DATA_MAX_NUM  5
struct data_packet {
	uint8 cmd_type;/*命令类型用于区分命令的主要目的*/
	uint8 cmd;/*这里是在命令类型下的具体操作命令*/
	uint8 ack;/*对处理结果的应答*/
	uint8 *data[DATA_MAX_NUM];/*相关指令的所附带的数据*/
};

enum {
    COMM_PARAM_NULL = 1,
    COMM_RECV_BYTE_ERR,
    COMM_ANAYL_HEAD_FIRST_ERR,
    COMM_ANAYL_HEAD_SECOND_ERR,
    COMM_ANAYL_LENGTH_ERR,
    COMM_ANAYL_LRC_ERR,
    COMM_SEND_ERR,
    COMM_RECV_ACK_ERR,
    COMM_CMD_OVERSTEP_ERR,
    COMM_FUNC_NULL_ERR,
    COMM_GET_FD_ERR,
    COMM_BIND_ERR,
    COMM_LISTEN_ERR,
    COMM_DATA_FIELD_LENGTH_ERR,
    COMM_GET_HOST_NAME_ERR,
    COMM_CONNECT_ERR,
};

/* 分析接收的数据的状态 */
enum {
  FREE = 0,
  ANALY_HEAD,
  ANALY_LEN,
  ANALY_DATA,
  ANALY_DONE,
};

extern int sever_comm_init(void);
extern int client_comm_init(void);
extern int recv_data(int recvfd, uint8 **data, uint16 *length);
extern int send_data(int sendfd, uint8 *data, uint16 length);
extern int package_data(struct data_packet *p_data_packet, 
                		uint8 **data, uint16 *length);
extern int analy_data(struct data_packet *p_data_packet, 
                	  uint8 *data, uint16 length); 


#endif